/*
 * Copyright (C) 2012 Rothens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rpg.server.net;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import rpg.server.RPGServer;

/**
 * rothens.tumblr.com
 * @author Rothens
 */
public class ListenThread {
	public volatile boolean isListening;
	private int id;
	public HashMap<InetAddress, Long> addresses;
	private Thread networkAcceptThread;
	private ServerSocket serverSocket;
	private ArrayList<LoginHandler> pendingConnections;
	
	public ListenThread(RPGServer rs, InetAddress address, int port) throws IOException {
		isListening = false;
		id = 0;
		addresses = new HashMap<InetAddress, Long>();
		pendingConnections = new ArrayList<LoginHandler>();
		serverSocket = new ServerSocket(port, 0, address);
		serverSocket.setPerformancePreferences(0, 2, 1);
		isListening = true;
		networkAcceptThread = new AcceptThread(this, "Listening thread", rs);
		networkAcceptThread.start();
	}
	
	public void removeSocket(Socket socket){
		InetAddress iaddress = socket.getInetAddress();
		synchronized (addresses){
			addresses.remove(iaddress);
		}
	}
	
	private void addPendingConnection(LoginHandler loginhandler){
		if(loginhandler == null){
			return;
		} else {
			pendingConnections.add(loginhandler);
			return;
		}
	}
	
	public void handleNetworkListenThread(){
		for(int i = 0; i < pendingConnections.size(); i++) {
			LoginHandler loginhandler = pendingConnections.get(i);
			try {
				loginhandler.tryLogin();
			} catch (Exception ex){
				loginhandler.kickUser("Server error");
			}
			if(loginhandler.finishedProcessing){
				pendingConnections.remove(i--);
			}
			loginhandler.netmanager.wakeThreads();
		}		
	}
	
	static ServerSocket getServerSocket(ListenThread listenthread){
		return listenthread.serverSocket;
	}
	
	static int addNetworkListenThread(ListenThread listenthread){
		return listenthread.id++;
	}
	
	static void addPendingConnection(ListenThread listenthread, LoginHandler loginhandler){
		listenthread.addPendingConnection(loginhandler);
	}
	
	static HashMap<InetAddress, Long> getAddresses(ListenThread listenthread){
		return listenthread.addresses;
	}
	
}
